<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户信息管理</title>
    <!--  引入bootstrap的css资源文件  -->
    <link th:href="@{bootstrap-3.4.1-dist/css/bootstrap.min.css}" type="text/css" rel="stylesheet">
    <!--    分页插件的样式表-->
    <link th:href="@{pagination-2.0.7/css/pagination.css}" type="text/css" rel="stylesheet">
    <!--  引入jquery的js资源文件【jquery资源文件要在所有的js资源文件之前】  -->
    <script type="text/javascript" th:src="@{jquery-1.12.4/jquery-1.12.4.min.js}"></script>
    <!--  引入bootstrap的js资源文件  -->
    <script type="text/javascript" th:src="@{bootstrap-3.4.1-dist/js/bootstrap.min.js}"></script>
    <!--  引入分页插件的js资源文件  -->
    <script type="text/javascript" th:src="@{pagination-2.0.7/js/pagination.min.js}"></script>

<!--    <script type="text/javascript">
        //////////////////////////////查询/////////////////////////////////////////////
        // 使用ajax进行用户信息查询
        //
        function doQuery() {
            // 使用ajax进行查询
            $.ajax({
                type: "post", // 请求类型： form表单的method属性
                url: "UserinfoQuery", // 请求的url路径， 等价于 from表单的 action属性
                data: $("#queryForm").serialize(), // 等价于form表单的数据串，例如："name=John&location=Boston"
                //contentType: 'application/json;charset=utf-8',//请求数据类型必须有
                dataType: "json", // 服务器返回的数据类型
                success: function (data) {  // 成功之后的回调函数 等价于ajax引擎的onreadystatechange事件的成功状态
                    // data参数就是服务器返回的数据 等价于 ajax引擎 responseText
                    //console.log("ddddddddddd:")
                    //console.log(data)
                    if (data) {
                        // 如果查询结果集不为空，则使用分页插件进行分页处理
                        // 把ajax查询的结果集使用分页插件进行分页处理
                        $('#datapager').pagination({
                            dataSource: data, // 分页的数据源 - 所有的数据记录
                            pageSize: 5,  // 每页显示的记录条数
                            showGoInput: true, // 显示跳转页数的输入框
                            showGoButton: true, // 显示跳转页数的按钮
                            pageNumber: 1, // 表示一开始默认加载的页码  也就是一开始就显示第几页
                            callback: function (pegedata, pagination) { // 点击页数或者跳转按钮之后的回调函数；更新当前页显示的数据集 pegedata
                                // pagination分页插件的对象自身的引用，可以获取分页插件相关的属性值
                                //pagination
                                console.log("pagination:::::::::::::")
                                console.log(pagination)
                                console.log("分页插件当页码："+pagination.pageNumber)
                                // 可以把当前页码 缓存到浏览器中  localstorage（永久的） 或者 sessionStorage （临时的）

                                // pegedata 就是分页插件当前页显示的数据集
                                // 把当前页显示的数据集，继续显示处理，局部更新页面
                                // 解析服务器发回的json对象，并将其内容显示到当前页面的表格中
                                // 遍历data数据集
                                // 拼接显示串
                                var strMsg = "";
                                // jquery提供的each函数进行遍历
                                $.each(pegedata, function (index, eachRow) {
                                    console.log("eachRow:")
                                    console.log(eachRow.userName)

                                    strMsg += "<tr>";
                                    strMsg += "  <th scope='row'>" + (index + 1) + "</th>";
                                    strMsg += "   <td>" + eachRow.username + "</td>";
                                    strMsg += "   <td>" + eachRow.useraddress + "</td>";
                                    strMsg += "   <td>" + eachRow.usertel + "</td>";
                                    strMsg += "   <td>" + eachRow.userbirthday + "</td>";
                                    strMsg += "   <td>" + eachRow.userregdate + "</td>";
                                    strMsg += "   <td><button onclick='showModifyModal(" + eachRow.userid + ")'>修改</button></td>";
                                    strMsg += "   <td><button onclick='deleteUserinfobyId(" + eachRow.userid + ")'>删除</button></td>";
                                    strMsg += "</tr>";
                                });
                                // 使用dom操作将拼接的结果显示字符串，赋值给 显示的表格对象
                                $("#showData").html(strMsg);

                            }
                        })
                    }
                },
                error: function () {
                    alert("查询失败！");
                }
            });
        }

        ////////////////////////////////新增保存///////////////////////////////////////////
        // 新增模态框的显示及初始化处理
        function showInsertModal() {
            // 显示新增的模态框
            $("#insertModal").modal('show');
            // 清空新增模块框的内容（防止遗留修改的内容）
            // 清空新增和查询使用的同一个form表单的控件值
            $("#insertForm")[0].reset();
            // reset方法对隐藏表单域不起作用，所以需要手动清空隐藏表单域的值
            $("#userId").val("");
        }

        // 新增保存操作
        function saveUserInfo() {
            // 使用ajax用户信息保存处理
            $.ajax({
                type: "POST", // 请求类型： form表单的method属性
                url: "UserInfoSave", // 请求的url路径， 等价于 from表单的 action属性
                data: $("#insertForm").serialize(), // 等价于form表单的数据串，例如："name=John&location=Boston"
                dataType: "json", // 服务器返回的数据类型
                success: function (data) {
                    // 提示信息
                    if (data && data.msg == "ok") {
                        alert("保存成功!");
                    } else {
                        alert("保存失败");
                    }
                    // 关闭模态框
                    $('#insertModal').modal('hide');

                    // 需要把jquery的对象转为dom对象，然后调用dom的reset方法
                    /*
                    jquery选择器选择的对象叫做jquery对象；jquery对象只能调用jquery的函数方法；不能调用原生的dom的方法；
                    反之，亦然；
                    使用 document.getElementById 获取的对象是原生的dom对象，原生的dom对象不能调用jquery的方法；只能调用原生dom方法；
                     */
                    // 在查询之前将查询表单的查询条件清空
                    $("#queryForm")[0].reset();
                    // 调用查询方法，显示数据
                    doQuery();
                }
            });
        }

        ///////////////////////////////修改////////////////////////////////////////
        function showModifyModal(uid) {
            // 复用新增的modal模态框
            $("#insertModal").modal('show');
            // 根据传入uid查询数据库的相关信息，然后将需要修改的信息更到到修改的页面
            $.ajax({
                type: "POST", // 请求类型： form表单的method属性
                url: "UserInfoQueryById", // 请求的url路径， 等价于 from表单的 action属性
                data: "uid=" + uid, // 等价于form表单的数据串，例如："name=John&location=Boston"
                dataType: "json", // 服务器返回的数据类型
                success: function (data) {
                    // 将查询到用户信息，显示到修改页面的form表单中
                    // 将来这里可以使用vue框架的双向数据绑定来进行迭代更新升级
                    if (data) {
                        // 将data中的值赋值给form表单的控制值
                        // 修改时，把当前记录的id，赋值给隐藏表单域
                        $("#userId").val(data.userid);

                        $("#userNameinsert").val(data.username);
                        $("#userAddressinsert").val(data.useraddress);
                        $("#userBirthdayinsert").val(data.userbirthday);
                        $("#userPswinsert").val(data.userpsw);
                        $("#userPswinsert2").val(data.userpsw);
                        $("#userTelinsert").val(data.usertel);
                    }
                }
            });
        }

        ///////////////////////////////删除操作///////////////////////////////
        function deleteUserinfobyId(uid) {
            // 使用confirm确认框，确认是否要进行删除
            var doornot = confirm("是否删除该条记录?");
            // 根据选择结果进行操作
            if (doornot == true) {
                // 进行删除操作
                // 根据传入uid逻辑删除数据库的相关信息
                $.ajax({
                    type: "POST", // 请求类型： form表单的method属性
                    url: "UserInfoDeleteById", // 请求的url路径， 等价于 from表单的 action属性
                    data: "uid=" + uid, // 等价于form表单的数据串，例如："name=John&location=Boston"
                    dataType: "json", // 服务器返回的数据类型
                    success: function (data) {
                        // 提示信息
                        if (data && data.msg == "ok") {
                            alert("删除成功!");
                        } else {
                            alert("删除失败");
                        }

                        // 在查询之前将查询表单的查询条件清空
                        $("#queryForm")[0].reset();
                        // 调用查询方法，显示数据
                        doQuery();
                    }
                });
            }
        }
    </script>-->
    <!--引入vue资源文佳 -->
    <script type="text/javascript" src="vue-2.6.14/vue.min.js"></script>
</head>
<body>
<div id="app">
    <div style="padding-top: 30px;">
        <form id="queryForm" class="form-horizontal">
            <div class="form-group">
                <label class="col-sm-2 control-label">用户名</label>
                <div class="col-sm-3">
                    <input type="text" class="form-control" id="userName" v-model="queryForm.username" placeholder="请输入用户名">
                </div>

                <label class="col-sm-2 control-label">地址</label>
                <div class="col-sm-3">
                    <input type="text" class="form-control" id="userAddress" v-model="queryForm.useraddress" placeholder="请输入地址">
                </div>
            </div>

            <div class="form-group">
                <label class="col-sm-2 control-label">电话</label>
                <div class="col-sm-3">
                    <input type="text" class="form-control" id="userTel" v-model="queryForm.usertel" placeholder="请输入电话">
                </div>

                <label class="col-sm-2 control-label">出生日期</label>
                <div class="col-sm-3">
                    <div class="col-sm-5">
                        <input type="date" class="form-control" id="userBirthday" v-model="queryForm.userbirthday" placeholder="开始日期">
                    </div>
                    <div class="col-sm-2">
                        -
                    </div>
                    <div class="col-sm-5">
                        <input type="date" class="form-control" id="userBirthday2" v-model="queryForm.userbirthday2"
                               placeholder="截至日期">
                    </div>

                </div>
            </div>

            <div class="form-group">
                <label class="col-sm-2 control-label">注册日期</label>
                <div class="col-sm-3">
                    <div class="col-sm-5">
                        <input type="date" class="form-control" id="userRegDate" v-model="queryForm.userregdate" placeholder="开始日期">
                    </div>
                    <div class="col-sm-2">
                        -
                    </div>
                    <div class="col-sm-5">
                        <input type="date" class="form-control" id="userRegDate2" v-model="queryForm.userregdate2" placeholder="截至日期">
                    </div>
                </div>
            </div>

            <div class="form-group">
                <div class="col-sm-offset-3 col-sm-3">
                    <button type="button" class="btn btn-default" @click="doQuery">查询</button>
                </div>
                <div class="col-sm-offset-3 col-sm-3">
                    <!-- 给按钮添加 data-toggle="modal" data-target="#insertModal" 这两个属性，则可以弹出模态框，#后面是模态框div的id值-->
                    <!--                <button type="button" class="btn btn-default" data-toggle="modal" data-target="#insertModal">新增</button>-->
                    <button type="button" class="btn btn-default" @click="showInsertModal()">新增</button>
                </div>
            </div>
        </form>
    </div>
    <div>
        <table class="table table-hover">
            <thead>
            <tr>
                <th>序号</th>
                <th>用户名</th>
                <th>地址</th>
                <th>电话</th>
                <th>出生日期</th>
                <th>注册日期</th>
                <th>修改</th>
                <th>删除</th>
            </tr>
            </thead>
            <tbody id="showData">
                <tr v-for="(item, index) in list">
                    <th>{{index+1}}</th>
                    <td>{{item.username}}</td>
                    <td>{{item.useraddress}}</td>
                    <td v-text="item.usertel"></td>
                    <td v-text="item.userbirthday"></td>
                    <td v-text="item.userregdate">
                    <td>
                        <button type="button" class="btn btn-danger" @click="showModifyModal(item.userid)">修改</button>
                    </td>
                    <td>
                        <button type="button" class="btn btn-success" @click="deleteUserinfobyId(item.userid)">删除</button>
                    </td>
                </tr>
            </tbody>
        </table>
        <div id="datapager"></div>
    </div>
    <!--新增modal模态框代码 开始-->
    <div id="insertModal" class="modal fade" tabindex="-1" role="dialog">
        <div class="modal-dialog" role="document" style="width: 1000px;">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
                    </button>
                    <h4 class="modal-title">用户信息修改</h4>
                </div>
                <div class="modal-body">
                    <!-- 模态框的主体内容  开始 -->
                    <form id="insertForm" class="form-horizontal">
                        <!-- 放置一个隐藏表单域，专门用于提交当前修改信息的id，如果是新增，则该字段为null -->
                        <input type="hidden" id="userId" v-model="insertOrUpdateForm.userid">
                        <div class="form-group">
                            <label class="col-sm-2 control-label">用户名</label>
                            <div class="col-sm-3">
                                <input type="text" class="form-control" id="userNameinsert" v-model="insertOrUpdateForm.username"
                                       placeholder="请输入用户名">
                            </div>

                            <label class="col-sm-2 control-label">地址</label>
                            <div class="col-sm-3">
                                <input type="text" class="form-control" id="userAddressinsert" v-model="insertOrUpdateForm.useraddress"
                                       placeholder="请输入地址">
                            </div>
                        </div>

                        <div class="form-group">
                            <label class="col-sm-2 control-label">电话</label>
                            <div class="col-sm-3">
                                <input type="text" class="form-control" id="userTelinsert" v-model="insertOrUpdateForm.usertel"
                                       placeholder="请输入电话">
                            </div>

                            <label class="col-sm-2 control-label">出生日期</label>
                            <div class="col-sm-3">
                                <input type="date" class="form-control" id="userBirthdayinsert" v-model="insertOrUpdateForm.userbirthday"
                                       placeholder="请输入出生日期">

                            </div>
                        </div>

                        <div class="form-group">
                            <label class="col-sm-2 control-label">密码</label>
                            <div class="col-sm-3">
                                <input type="password" class="form-control" id="userPswinsert" v-model="insertOrUpdateForm.userpsw"
                                       placeholder="请输入密码">
                            </div>

                            <label class="col-sm-2 control-label">确认密码</label>
                            <div class="col-sm-3">
                                <input type="password" class="form-control" id="userPswinsert2"
                                       placeholder="请输入确认密码">
                            </div>
                        </div>
                    </form>
                    <!-- 模态框的主体内容  结束 -->
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                    <button type="button" class="btn btn-primary" @click="saveUserInfo">保存</button>
                </div>
            </div><!-- /.modal-content -->
        </div><!-- /.modal-dialog -->
    </div><!-- /.modal -->
    <!--新增modal模态框代码 结束-->
</div>
<script type="text/javascript" src="axios-0.21.1/axios.min.js"></script>
<script type="text/javascript" src="qs-6.10.1/qs.js"></script>
<script type="text/javascript">
    //创建vue对象
    var vue = new Vue({
        el: '#app',
        data: {
            queryForm: {
                username: '',
                useraddress: '',
                usertel: '',
                userbirthday: '',
                userbirthday2: '',
                userregdate: '',
                userregdate2: ''
            },
            list: [],
            insertOrUpdateForm: {
                userid: null,
                username: "",
                usertel: "",
                useraddress: "",
                userbirthday: "",
                userpsw: ""
            }
        },
        methods: {
            saveUserInfo: function() {
                var it = this;
                axios.post('UserInfoSave',Qs.stringify(it.insertOrUpdateForm))
                .then(function(success) {
                    // 提示信息
                    if (success.data && success.data.msg == "ok") {
                        alert("保存成功!");
                    } else {
                        alert("保存失败");
                    }
                    // 关闭模态框
                    $('#insertModal').modal('hide');

                    // 需要把jquery的对象转为dom对象，然后调用dom的reset方法
                    /*
                    jquery选择器选择的对象叫做jquery对象；jquery对象只能调用jquery的函数方法；不能调用原生的dom的方法；
                    反之，亦然；
                    使用 document.getElementById 获取的对象是原生的dom对象，原生的dom对象不能调用jquery的方法；只能调用原生dom方法；
                     */
                    // 在查询之前将查询表单的查询条件清空
                    $("#queryForm")[0].reset();
                    // 调用查询方法，显示数据
                    it.doQuery();
                })
            },

            showModifyModal: function(uid) {
                var it = this;
                $("#insertModal").modal('show');
                $("#insertForm")[0].reset();
                var str = "uid="+uid;
                axios.post('UserInfoQueryById',str)
                .then(function(success) {
                    if(success.data) {
                        it.insertOrUpdateForm = success.data
                    }
                })
            },
            showInsertModal: function() {
                // 显示新增的模态框
                $("#insertModal").modal('show');
                // 清空新增模块框的内容（防止遗留修改的内容）
                // 清空新增和查询使用的同一个form表单的控件值
                //$("#insertForm")[0].reset();
                this.insertOrUpdateForm={}
                // reset方法对隐藏表单域不起作用，所以需要手动清空隐藏表单域的值
                //$("#userId").val("");
                //使用vue的方式清空userId
                this.insertOrUpdateForm.userid = null;
            },
            doQuery: function() {
                var it = this;
                console.log("start")
                console.log(JSON.stringify(it.queryForm))
                console.log(Qs.stringify(it.queryForm))
                console.log("结束")
                axios.post('UserinfoQuery', Qs.stringify(it.queryForm))
                    .then(function(result) {
                        console.log(result.data)
                        //分页显示
                        if (result.data) {
                            // 如果查询结果集不为空，则使用分页插件进行分页处理
                            // 把ajax查询的结果集使用分页插件进行分页处理
                            $('#datapager').pagination({
                                dataSource: result.data, // 分页的数据源 - 所有的数据记录
                                pageSize: 5,  // 每页显示的记录条数
                                showGoInput: true, // 显示跳转页数的输入框
                                showGoButton: true, // 显示跳转页数的按钮
                                pageNumber: 1, // 表示一开始默认加载的页码  也就是一开始就显示第几页
                                callback: function (pegedata, pagination) { // 点击页数或者跳转按钮之后的回调函数；更新当前页显示的数据集 pegedata
                                    it.list = pegedata
                                }
                            })
                        }

                    })
                    .catch(function(error) {
                        console.log(error)
                    })
                }
            }
    })
</script>

</body>
</html>
springmvc 页面传来参数中文乱码（过滤器）、Date类型转换器(类型服务工厂bean,然后放在mvc:annocation-diven注解属性中)
@responseBody注解，方法返回值为非String时，如何将其转换为json字符串，需要引入三个依赖（版本不能太低），有两种总方式，一种mvc:annocation-diven，另一种是处理器适配器
json返回date字符串https://www.cnblogs.com/jsczljh/p/3654636.html，public class CustomDateSerializer extends JsonSerializer<Date>  @JsonSerialize(using= CustomDateSerializer.class)